package models

import (
	"blog/utils"
	"strings"
	"time"
)

// 分页获取简略文章
func GetSmallArticlesByPage(page, limit uint, text string, column int, tags []uint) ([]*SmallArticle, error) {
	var as []Article
	query := db.Joins("Column")
	if column >= 0 {
		query = query.Where("column_id = ?", column)
	}
	if len(tags) > 0 {
		query = query.Preload("Tags", "id in ?", tags)
	} else {
		query = query.Preload("Tags")
	}
	query = query.Select("`articles`.`id`", "title", "abstract", "view", "cover", "create_time", "update_time")
	if text != "" {
		chars := []rune(text)
		var buf strings.Builder
		buf.WriteByte('%')
		for _, c := range chars {
			buf.WriteRune(c)
			buf.WriteByte('%')
		}
		query = query.Where("title like ?", buf.String())
	}
	query = query.Limit(int(limit)).Offset(int(limit * (page - 1))).Order("create_time desc").Find(&as)
	if err := query.Error; err != nil {
		return nil, err
	}
	res := make([]*SmallArticle, len(as))
	for i, a := range as {
		res[i] = a.ToSmallArticle()
	}
	return res, nil
}

// 获取文章
func GetArticle(article Article) (*Article, error) {
	query := db.Preload("Tags").Joins("Column").First(&article)
	return &article, query.Error
}

// 保存文章
func SaveArticle(article *Article) (*Article, error) {
	if article.Cover == "" {
		img, err := utils.GetBingImage()
		if err != nil {
			return nil, err
		}
		article.Cover = img
	}
	err := db.Save(article).Error
	return article, err
}

// 删除文章
func DeleteArticle(article Article) (*Article, error) {
	err := db.Delete(&article).Error
	return &article, err
}

// 删除多个文章
func DeleteArticles(as []Article) ([]Article, error) {
	t := db.Begin()
	for i := range as {
		if err := t.Delete(&as[i]).Error; err != nil {
			t.Callback()
			return nil, err
		}
	}
	if err := t.Commit().Error; err != nil {
		t.Callback()
		return nil, err
	}
	return as, nil
}

// 获取文章阅读量
func GetArticleView(id uint) (uint, error) {
	var view uint
	err := db.Model(new(Article)).Select("view").Where("id = ?", id).First(&view).Error
	return view, err
}

// 更改文章阅读量
func UpdateArticle(id, view uint) error {
	return db.Model(new(Article)).Where("id = ?", id).Update("view", view).Error
}

// 文章
type Article struct {
	Id         uint      `gorm:"primarykey" json:"id"`
	Title      string    `gorm:"not null;unique" json:"title"`                                                     // 标题
	Abstract   string    `gorm:"default:''" json:"abstract"`                                                       // 简介
	View       uint      `gorm:"default:0" json:"view"`                                                            // 浏览量
	Tags       []Tag     `gorm:"many2many:article_tags;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"tags"` // 标签
	ColumnId   uint      `json:"-"`                                                                                // 专栏id
	Column     Column    `gorm:"constraint:OnUpdate:CASCADE;" json:"column"`                                       // 专栏
	Text       string    `gorm:"type:text;default:''" json:"text"`                                                 // 正文
	Cover      string    `gorm:"default:''" json:"cover"`                                                          // 封面
	CreateTime time.Time `json:"create_time"`
	UpdateTime time.Time `json:"update_time"`
}

// 转成简略文章
func (self *Article) ToSmallArticle() *SmallArticle {
	return &SmallArticle{
		Id:         self.Id,
		Title:      self.Title,
		Abstract:   self.Abstract,
		View:       self.View,
		Tags:       self.Tags,
		Column:     self.Column,
		Cover:      self.Cover,
		CreateTime: self.CreateTime,
		UpdateTime: self.UpdateTime,
	}
}

// 简略文章
type SmallArticle struct {
	Id         uint      `json:"id"`
	Title      string    `json:"title"`
	Abstract   string    `json:"abstract"`
	View       uint      `json:"view"`
	Tags       []Tag     `json:"tags"`
	Column     Column    `json:"column"`
	Cover      string    `json:"cover"`
	CreateTime time.Time `json:"create_time"`
	UpdateTime time.Time `json:"update_time"`
}
